package com.xuecheng.content.service.bloom;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.xuecheng.base.constant.CoursePublishStatusConstant;
import com.xuecheng.content.constant.CourseCacheConstant;
import com.xuecheng.content.model.dto.CourseBaseInfoDTO;
import com.xuecheng.content.model.dto.CoursePreviewDTO;
import com.xuecheng.content.model.dto.TeachPlanDTO;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.content.model.po.CourseTeacher;
import com.xuecheng.content.service.ICoursePublishService;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 勾新杰
 * @version 1.0
 * @description:
 * @date 2025/3/19 14:00
 */
@Component
@RequiredArgsConstructor
public class CourseBloomFilterInitializer {

    /**
     * redission客户端
     */
    private final RedissonClient redissonClient;

    /**
     * 课程发布服务
     */
    private final ICoursePublishService coursePublishService;

    /**
     * redis模板
     */
    private final RedisTemplate<String, String> redisTemplate;

    /**
     * 针对课程的布隆过滤器
     */
    @Getter
    private RBloomFilter<Long> courseBloomFilter;

    /**
     * 在执行完构造器后初始化布隆过滤器
     */
    @PostConstruct
    public void init() {
        // 1. 获取、初始化布隆过滤器
        courseBloomFilter = redissonClient.getBloomFilter("courseBloomFilter");
        courseBloomFilter.tryInit(100000L, 0.01);
        // 2. 查询满足条件的发布课程
        List<CoursePublish> coursePublishList = coursePublishService.lambdaQuery()
                .eq(CoursePublish::getStatus, CoursePublishStatusConstant.PUBLISHED)
                .list();
        // 3. 遍历课程，将课程id添加到布隆过滤器中并进行缓存预热
        coursePublishList.forEach(
                coursePublish -> {
                    // 3.1 初始化布隆过滤器
                    Long courseId = coursePublish.getId();
                    courseBloomFilter.add(courseId);
                    // 3.2 缓存预热
                    CoursePreviewDTO coursePreviewDTO = coursePublishService.getCoursePublishWhole(courseId);
                    redisTemplate.opsForValue().set(
                            CourseCacheConstant.KEY_PREFIX + courseId,
                            JSON.toJSONString(coursePreviewDTO),
                            CourseCacheConstant.KEY_EXPIRE_MINUTES * 60 + ThreadLocalRandom.current().nextInt(coursePublishList.size()),
                            TimeUnit.SECONDS
                    );
                }
        );
    }
}
